import { Button, Typography, Box, Snackbar, Alert } from '@mui/material';
import React, { useCallback, memo } from 'react';

import { createCounterStore, createStoreHook, CounterAction } from '../utils/stateManagement/store';

// 为每个组件实例创建独立的store
const createStore = () => {
  const store = createCounterStore();
  return store;
};

interface CounterProps {
  initialCount?: number;
}

// 创建错误边界组件
class CounterErrorBoundary extends React.Component<
  { children: React.ReactNode },
  { hasError: boolean }
> {
  constructor(props: { children: React.ReactNode }) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error('Counter Error:', error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return (
        <Box sx={{ p: 2, textAlign: 'center' }}>
          <Typography color="error">Something went wrong with the counter.</Typography>
          <Button
            variant="contained"
            onClick={() => this.setState({ hasError: false })}
            sx={{ mt: 1 }}
          >
            Try Again
          </Button>
        </Box>
      );
    }

    return this.props.children;
  }
}

// 创建按钮组件
const CounterButton = memo<{
  onClick: () => void;
  variant: 'contained' | 'outlined';
  children: React.ReactNode;
}>(({ onClick, variant, children }) => (
  <Button variant={variant} onClick={onClick} sx={{ minWidth: 100 }}>
    {children}
  </Button>
));

CounterButton.displayName = 'CounterButton';

export const Counter: React.FC<CounterProps> = ({ initialCount = 0 }) => {
  const store = React.useMemo(() => createStore(), []);
  const useCounterStore = React.useMemo(() => createStoreHook(store), [store]);
  const [state, dispatch] = useCounterStore();
  const [error, setError] = React.useState<string | null>(null);

  // 初始化计数器
  React.useEffect(() => {
    if (initialCount !== 0) {
      try {
        dispatch({ type: 'RESET' });
        if (initialCount > 0) {
          dispatch({ type: 'INCREMENT', payload: initialCount });
        } else {
          dispatch({ type: 'DECREMENT', payload: -initialCount });
        }
      } catch (err) {
        setError('Failed to initialize counter');
      }
    }
  }, [initialCount, dispatch]);

  // 处理动作分发
  const handleDispatch = useCallback(
    (action: CounterAction) => {
      try {
        dispatch(action);
      } catch (err) {
        setError(`Failed to ${action.type.toLowerCase()} counter`);
      }
    },
    [dispatch],
  );

  // 创建处理函数
  const handleIncrement = useCallback(() => {
    handleDispatch({ type: 'INCREMENT' });
  }, [handleDispatch]);

  const handleDecrement = useCallback(() => {
    handleDispatch({ type: 'DECREMENT' });
  }, [handleDispatch]);

  const handleReset = useCallback(() => {
    handleDispatch({ type: 'RESET' });
  }, [handleDispatch]);

  const handleCloseError = useCallback(() => {
    setError(null);
  }, []);

  return (
    <CounterErrorBoundary>
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          gap: 2,
          p: 2,
          border: '1px solid #ddd',
          borderRadius: 1,
          boxShadow: 1,
        }}
      >
        <Typography variant="h4" component="h1">
          Count: {state.count}
        </Typography>
        <Typography variant="caption" color="text.secondary">
          Last updated: {new Date(state.lastUpdated).toLocaleTimeString()}
        </Typography>
        <Box sx={{ display: 'flex', gap: 1 }}>
          <CounterButton onClick={handleIncrement} variant="contained">
            Increment
          </CounterButton>
          <CounterButton onClick={handleDecrement} variant="contained">
            Decrement
          </CounterButton>
          <CounterButton onClick={handleReset} variant="outlined">
            Reset
          </CounterButton>
        </Box>
      </Box>
      <Snackbar open={!!error} autoHideDuration={6000} onClose={handleCloseError}>
        <Alert onClose={handleCloseError} severity="error" sx={{ width: '100%' }}>
          {error}
        </Alert>
      </Snackbar>
    </CounterErrorBoundary>
  );
};
